/* 
1 分析页面的数据来源
  1 当前城市
    1 来自于 redux   
  2 热门城市  
    1 来自于 接口 
  3 所有城市 
    1 来自于 接口 
2 如何组装数据 方便我们使用!!! 
3 在 组件挂载完毕中
  1 组件挂载执行快 
  2 异步请求获取当前城市的数据 还没没有回来
  3 组件视图中 却又会显示 真实 广州市 
  4 如何解决 ?? 
    1 在组件更新 周期  做一些处理   死循环
    2 shouldComponentUpdate 决定组件是否要更新 
      1 一定能够拿到 最新的城市
      2 思考一个 是否允许更新条件
      3 如何避免 死循环
    3 使用订阅 
      1 一定能够拿到 
      2 订阅 原生redux
      3 react-redux 
    4 在根组件中 App.js  条件渲染
      1 当前城市回来了 才去渲染 所有的路由页面 
      2 根组件挂载完毕 -> 获取当前城市名称 -> 才会去渲染 其他的页面 -> 页面的 组件挂载完毕事件才会触发
4 如何使用react第三放 组件
  1 组件的属性
    1 一般都是直接在 组件的标签上使用 
  2 组件的方法 !! 
    1 一般通过 ref 非受控表单来使用!!! 和 vue 很相似 this.$refs....
  3 组件的事件 通过绑定属性来使用

 */

import React, { Component } from 'react';
import { NavBar, Icon } from 'antd-mobile';
import { request as axios } from "../../utils/request";

import { connect } from "react-redux";
import indexCss from "./index.module.scss";
import { List } from 'react-virtualized';
import { initCity } from "../../store/actionCreator";
console.log("城市列表");

class Index extends Component {
  state = {
    // 城市列表
    cityList: [],
    // 字母列表
    letterList: [],
    // 当前显示的字母
    currentIndex: 0
  }

  constructor(){
    super();
    // 创建一个联系 一条线
    this.refList=React.createRef();
  }


  async componentDidMount() {
    // 1 先获取一下 redux中的热门城市的 数据
    // console.log(this.props.cityName);
    // 2 热门城市
    // axios 封装过基础路径  但是 发现传递了完整地址的话 它会忽略掉 基础路径
    // axios.get("https://api-haoke-web.itheima.net/home/swiper") 
    // axios.get("/area/hot")
    // .then(console.log);

    // axios.get("/area/city?level=1")
    // .then(console.log);

    // 当前城市
    // this.props.cityName 

    const resList = await Promise.all([this.getHots(), this.getAllCitys()]);
    // console.log(resList);
    // 热门城市
    const hots = resList[0].data.body;
    // 所有城市
    const allCitys = resList[1].data.body;

    // 综合数组 需要 把所有数据都拼接起来
    const list = [{ name: "当前定位", list: [this.props.cityName] }];
    // 存放 热门城市
    list.push({ name: "热门城市", list: hots.map(v => v.label) });

    // 所有城市  有一丢困难 排序!!   
    // 普通数组排序  很简单
    // 对象数组排序  很简单!!! 
    // allCitys.sort((a, b) => a.short.localeCompare(b.short));
    console.log(allCitys.sort((a, b) => a.short.localeCompare(b.short)));

    // 声明一个字母列表
    let letterList = ["#", "热"];

    // 对 所有城市数组 进行处理 将它改造成 满足要求数组格式
    allCitys.forEach(v => {
      // v {label: "安庆", value: "AREA|b4e8be1a-2de2-e039", pinyin: "anqing", short: "aq"}
      // list =  [ 
      // { "name": "当前定位", "list": [ "广州" ] },
      //  { "name":"热门城市", "list":["北京","广州","深圳","上海"] }],

      // 获取所有城市中的 short 里面 第一个字母
      const firstLetter = v.short[0].toUpperCase();// A
      // 判断 A
      const index = list.findIndex(vv => vv.name === firstLetter);
      if (index === -1) {
        // 没有找到
        list.push({ name: firstLetter, list: [v.label] });
        letterList.push(firstLetter);
      } else {
        // 找到了 
        //  list[index]  = { "name":"B", "list":["北京"] }
        list[index].list.push(v.label);
      }
    })

    this.setState({ cityList: list, letterList });

    // 才开始组装 promiseall 
  }

  // 获取热门城市
  getHots = () => {
    return axios.get("/area/hot")
  }

  // 获取所有城市
  getAllCitys = () => {
    return axios.get("/area/city?level=1")
  }

  // 每一个城市的渲染函数
  rowRenderer = ({
    key, // Unique key within array of rows
    index, // Index of row within collection
    isScrolling, // The List is currently being scrolled
    isVisible, // This row is visible within the List (eg it is not an overscanned row)
    style, // Style object to be applied to row (to position it)
  }) => {
    const { cityList } = this.state;
    return (
      <div key={key} style={style}>
        <div className={indexCss.city_group_title}>{cityList[index].name}</div>
        <div className={indexCss.city_group_content}>
          {cityList[index].list.map((v, i) => <div
            onClick={() => this.cityClick(v)}
            key={i} className={indexCss.city_item} >
            {v}
          </div>)}
        </div>
      </div>
    );
  }

  // List组件的每一行多高函数
  rowHeight = ({ index }) => {
    const { cityList } = this.state;
    // console.log(index);
    // 来计算每一行的高度 即可
    // 标题:40  小循环项 :40
    return 40 + cityList[index].list.length * 40;
  }

  //   数组被渲染的每一行的回调函数 
  onRowsRendered = ({ startIndex }) => {
    // startIndex  当前被显示的 索引 
    // console.log(startIndex);
    this.setState({ currentIndex: startIndex });
  }

  // 字母列表的点击事件
  letterClick = (currentIndex) => {
    this.setState({ currentIndex });
    // 让List组件滚动到 具体行中 
    this.refList.current.scrollToRow(currentIndex);
  }

  // 点击城市名称
  cityClick = (cityName) => {
    /* 
    1 获取被点击的城市名称
    2 修改redux中的城市名称 同步!! 
    3 返回上一页!! 
     */
    this.props.handleInitCity(cityName); // 经历挺多步骤  细心!! 
    // 返回上一页! 
    this.props.history.goBack();
  }

  render() {
    const { cityList, letterList, currentIndex } = this.state;
    return (
      <div>
        <NavBar
          mode="light"
          icon={<Icon type="left" />}
          onLeftClick={this.props.history.goBack}
        >城市选择</NavBar>

        <div className={indexCss.city_content}>
          <div className={indexCss.city_list}>
            <List
              ref={this.refList}
              width={window.innerWidth}
              height={window.innerHeight - 45}
              rowCount={cityList.length}
              rowHeight={this.rowHeight}
              rowRenderer={this.rowRenderer}
              // scrollToIndex={currentIndex}
              scrollToAlignment="start"
              onRowsRendered={this.onRowsRendered}
            />
          </div>

          {/* 字母列表 */}
          <div className={indexCss.letter_list}>
            {letterList.map((v, i) => <div key={v}
              onClick={() => this.letterClick(i)}
              className={
                [
                  indexCss.letter_item,
                  i === currentIndex ? indexCss.active : ''
                ].join(" ")
              }  >
              <span>{v}</span>
            </div>)}
          </div>
        </div>


      </div>
    );
  }
}


const mapStateToProps = (state) => ({
  cityName: state.cityReducer.cityName
})

const mapDispatchToProps = (dispatch) => ({
  handleInitCity(cityName) {
    dispatch(initCity(cityName));
  }
})

export default connect(mapStateToProps, mapDispatchToProps)(Index);